import DragonNode from './DragonNode';
import TableMgr from '../manager/TableMgr';

export class DragonManager {
  private static manager: DragonManager;
  private pool: any;
  private dragonAssetList: any;
  private dragonAtlasAssetList: any;
  //获取单例对象
  public static getInstance(initCallback?: Function): DragonManager {
    if (DragonManager.manager == null) {
      DragonManager.manager = new DragonManager();
    }
    return DragonManager.manager;
  }
  public constructor() {
    this.pool = {};
    this.dragonAssetList = {};
    this.dragonAtlasAssetList = {};
  }
  // public cache(models: Array<number>, effects: Array<string>, callback: Function, proCallback: Function) {
  //     var urls = [];
  //     for (var i = 0; i < models.length; i++) {
  //         var conf:res_dragonNode = TableMgr.inst.getDragonConfigById(models[i]);
  //         urls.push({ res: conf.path, armature: conf.baseBone });
  //     }
  //     for (var i = 0; i < effects.length; i++) {
  //         var conf = API.getConfTable("effects").getRowByIndex("name", effects[i]);
  //         urls.push({ res: conf.path, armature: conf.aName });
  //     }
  //     if (urls.length == 0) {
  //         callback();
  //     } else {
  //         this.cacheByIndex(urls, 0, callback, proCallback);
  //     }
  // }
  private cacheByIndex(list: any, index: number, callback: Function, proCallback: Function) {
    //cc.log(list, index)
    var self = this;
    if (proCallback) proCallback(index / list.length);
    if (index >= list.length) {
      callback();
      return;
    }
    var data = list[index];
    var modelUrl = data.res;
    var armatureName = data.armature;
    if (this.dragonAssetList[modelUrl] == null) {
      cc.log('资源缓存:' + modelUrl);
      cc.loader.loadResDir(modelUrl, function (err, assets) {
        for (let i = 0; i < assets.length; i++) {
          if (assets[i] instanceof dragonBones.DragonBonesAsset) {
            self.dragonAssetList[modelUrl] = assets[i];
          }
          if (assets[i] instanceof dragonBones.DragonBonesAtlasAsset) {
            self.dragonAtlasAssetList[modelUrl] = assets[i];
          }
        }
        index++;
        self.cacheByIndex(list, index, callback, proCallback);
      });
    } else {
      cc.log('资源已经存在不需要缓存:' + modelUrl);
      index++;
      this.cacheByIndex(list, index, callback, proCallback);
    }
  }
  public getModel(modelUrl: string, armatureName: string, scale: number = 1): DragonNode {
    //cc.log("获取模型：" + modelUrl + ":" + armatureName);
    var self = this;
    let model: DragonNode = null;
    let armatureDisplay: dragonBones.ArmatureDisplay = null;
    // cc.log(modelUrl);
    if (this.pool[modelUrl] != null && this.pool[modelUrl].length > 0) {
      //cc.log("返回缓存模型:" + modelUrl);
      model = this.pool[modelUrl].shift();
      //cc.log("模型:",model);
      model.startReady();
      armatureDisplay = model.armatureDisplay;
      armatureDisplay.armatureName = armatureName;
      model.onReady();
    } else {
      //cc.log("构造新模型:" + modelUrl);
      model = new DragonNode();
      model.resUrl = modelUrl;
      model.startReady();
      armatureDisplay = model.armatureDisplay;
      if (this.dragonAssetList[modelUrl] == null) {
        cc.loader.loadResDir(modelUrl, function (err, assets) {
          for (let i = 0; i < assets.length; i++) {
            //cc.log(assets[i]);

            if (assets[i] instanceof dragonBones.DragonBonesAsset) {
              armatureDisplay.dragonAsset = assets[i];
              self.dragonAssetList[modelUrl] = assets[i];
            }
            if (assets[i] instanceof dragonBones.DragonBonesAtlasAsset) {
              armatureDisplay.dragonAtlasAsset = assets[i];
              self.dragonAtlasAssetList[modelUrl] = assets[i];
            }
          }
          armatureDisplay.armatureName = armatureName;
          model.onReady();
        });
      } else {
        armatureDisplay.dragonAsset = this.dragonAssetList[modelUrl];
        armatureDisplay.dragonAtlasAsset = this.dragonAtlasAssetList[modelUrl];
        armatureDisplay.armatureName = armatureName;
        model.onReady();
      }
    }

    model.scale = scale;
    return model;
  }
  public putModel(model: DragonNode) {
    if (this.pool[model.resUrl] == null) {
      this.pool[model.resUrl] = [];
    }
    this.pool[model.resUrl].push(model);
  }
  public getEffects(name: string): DragonNode {
    var cData: res_dragonEffect = TableMgr.inst.getEffectByName(name);
    if (cData == null) {
      cc.log('获取未知的特效资源：' + name);
      return null;
    }

    return this.getModel(cData.url, cData.boneName, cData.scale);
  }
  public getModelByModelId(id: number): DragonNode {
    var cData: res_dragonNode = TableMgr.inst.getDragonConfigById(id);
    if (cData == null) {
      cc.log('获取未知的Model资源：' + id);
      return null;
    }
    return this.getModel(cData.path, cData.baseBone);
  }

  public static getModel(modelUrl: string, armatureName: string): DragonNode {
    return DragonManager.getInstance().getModel(modelUrl, armatureName);
  }
  public static getModelByModelId(id: number): DragonNode {
    return DragonManager.getInstance().getModelByModelId(id);
  }
  public static getEffects(name: string): DragonNode {
    return DragonManager.getInstance().getEffects(name);
  }
  public static putModel(model: DragonNode) {
    DragonManager.getInstance().putModel(model);
  }

  public static addEffect(
    node: cc.Node,
    name: string,
    action: string,
    actionType: number,
    func: Function = null,
    obj: any = null,
  ): DragonNode {
    let model: DragonNode = DragonManager.getEffects(name);
    if (!model.parent) {
      node.addChild(model);
    } else {
      // model =  ModelManager.getEffects(name);
      model.stopAnimation();
      model.removeFromParent(true);
      DragonManager.resetNode(model);
      model.targetOff(model);
      model.parent = node;
    }
    model.playAnimation(action, actionType);
    if (actionType == 1) {
      let playDone: any = () => {
        model.stopAnimation();
        model.removeFromParent(true);
        DragonManager.resetNode(model);
        model.targetOff(model);
        model.removeEventListener(dragonBones.EventObject.COMPLETE, playDone, this);
        //if(name!="baozha"){
        DragonManager.putModel(model);
        //}
        if (func && obj) {
          func.apply(obj);
        }
      };
      model.addEventListener(dragonBones.EventObject.COMPLETE, playDone, this);
    }
    return model;
  }

  public static playDone(): void {}

  public static resetNode(node: DragonNode): void {}
}
